package com.gelian.geliansdk.control;

import com.gelian.geliansdk.GlEngine;
import com.gelian.geliansdk.GlResultCode;
import com.gelian.geliansdk.callback.GlCallback;
import com.gelian.geliansdk.callback.RequestDeviceValueCallback;
import com.gelian.geliansdk.listener.GlDeviceValueListener;
import com.gelian.geliansdk.listener.GlDeviceValueListenerBase;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class GlG1Controller {
    public static final int ID_LED_R = 0;
    public static final int ID_LED_G = 1;
    public static final int ID_LED_B = 2;
    public static final int ID_T = 3;
    public static final int ID_RH = 4;
    public static final int ID_GRAVITY_X = 5;
    public static final int ID_GRAVITY_Y = 6;
    public static final int ID_GRAVITY_Z = 7;
    public static final int ID_IR_RECODE = 8;
    public static final int ID_IR_RECODE_OK = 9;
    public static final int ID_IR_REPLAY = 10;
    public static final int ID_BUZZER = 11;
    public static final int ID_GRAVITY_TAP = 12;
    public static final int ID_BUTTON_SW1 = 13;
    public static final int ID_VIBRATION_SWITCH = 14;
    public static final int ID_REED_SWITCH = 15;
    public static final int ID_DETECT_IR = 16;
    public static final int ID_DETECT_LIGHT = 17;
    public static final int ID_MOTOR_ON = 18;
    public static final int ID_MOTOR_DIRECTION = 19;
    public static final int ID_DEV_NAME = 20;

    public static final Map<Integer, Object> CTRL_MAP = new HashMap<>();
    public static final Set<Integer> REQUEST_SET = new HashSet<>();
    public static final Map<String, Map<Integer, GlDeviceValueListenerBase>> LISTENER_MAP = new HashMap<>();

    static {
        GlEngine.setDeviceValueListener(new GlDeviceValueListener() {
            @Override
            public void done(String imei, Map<Integer, Object> map_id_value) {
                Map<Integer, GlDeviceValueListenerBase> deviceValueListenerMap = LISTENER_MAP.get(imei);
                if (deviceValueListenerMap != null) {
                    Set<Integer> keySet = map_id_value.keySet();
                    for (int char_id : keySet) {
                        GlDeviceValueListenerBase valueListenerBase = deviceValueListenerMap.get(char_id);
                        if (valueListenerBase != null) {
                            Object valu = map_id_value.get(char_id);
                            valueListenerBase.done(valu);
                        }
                    }
                }
            }
        });
    }

    public static abstract class RequestTAndRhValueCallback extends RequestDeviceValueCallback {
        public abstract void done(int resultCode, int value_t, int value_rh);

        @Override
        public void done(int resultCode, HashMap<Integer, Object> var) {
            int value_t = 0;
            int value_rh = 0;
            if (resultCode == GlResultCode.GL_CALLBACK_CODE_SUCCESS) {
                Object obj_t = var.get(ID_T);
                Object obj_rh = var.get(ID_RH);
                try {
                    value_t = Integer.parseInt(obj_t.toString());
                    value_rh = Integer.parseInt(obj_rh.toString());

                } catch (Exception e) {

                }
            }
            done(resultCode, value_t, value_rh);
        }
    }

    public static void requestTAndRhValue(String imei, RequestTAndRhValueCallback callback) {
        REQUEST_SET.clear();
        REQUEST_SET.add(ID_T);
        REQUEST_SET.add(ID_RH);
        GlEngine.requestDeviceValue(imei, REQUEST_SET, callback);
    }

    public static abstract class RequestGravityCallback extends RequestDeviceValueCallback {
        public abstract void done(int resultCode
                , int value_gravity_x
                , int value_gravity_y
                , int value_gravity_z
        );

        @Override
        public void done(int resultCode, HashMap<Integer, Object> var) {
            int value_gravity_x = 0;
            int value_gravity_y = 0;
            int value_gravity_z = 0;
            if (resultCode == GlResultCode.GL_CALLBACK_CODE_SUCCESS) {
                value_gravity_x = (int) var.get(ID_GRAVITY_X);
                value_gravity_y = (int) var.get(ID_GRAVITY_Y);
                value_gravity_z = (int) var.get(ID_GRAVITY_Z);
            }
            done(resultCode
                    , value_gravity_x
                    , value_gravity_y
                    , value_gravity_z
            );
        }
    }

    public static void requestGravity(String imei, RequestGravityCallback callback) {
        REQUEST_SET.clear();
        REQUEST_SET.add(ID_GRAVITY_X);
        REQUEST_SET.add(ID_GRAVITY_Y);
        REQUEST_SET.add(ID_GRAVITY_Z);
        GlEngine.requestDeviceValue(imei, REQUEST_SET, callback);
    }


    public static void setBuzzerValue(String imei, int value, GlCallback callback) {
        CTRL_MAP.clear();
        CTRL_MAP.put(ID_BUZZER, value);
        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setButtonSw1Value(String imei, int value, GlCallback callback) {
        CTRL_MAP.clear();
        CTRL_MAP.put(ID_BUTTON_SW1, value);
        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }


    public interface ButtonSW1ValueListener extends GlDeviceValueListenerBase<Integer> {
    }

    public static void setButtonSW1ValueListener(String imei, ButtonSW1ValueListener listener) {
        Map<Integer, GlDeviceValueListenerBase> deviceValueListenerBaseMap = LISTENER_MAP.get(imei);
        if (deviceValueListenerBaseMap == null) {
            deviceValueListenerBaseMap = new HashMap<>();
            LISTENER_MAP.put(imei, deviceValueListenerBaseMap);
        }
        deviceValueListenerBaseMap.put(ID_BUTTON_SW1, listener);
    }


    public static void setValue(String imei, int char_id, int char_value, GlCallback callback) {
        CTRL_MAP.clear();
        CTRL_MAP.put(char_id, char_value);
        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }


    public static void setListener(String imei, int char_id, GlDeviceValueListenerBase listener) {
        Map<Integer, GlDeviceValueListenerBase> deviceValueListenerBaseMap = LISTENER_MAP.get(imei);
        if (deviceValueListenerBaseMap == null) {
            deviceValueListenerBaseMap = new HashMap<>();
            LISTENER_MAP.put(imei, deviceValueListenerBaseMap);
        }
        deviceValueListenerBaseMap.put(char_id, listener);
    }


    public static void setMotorDirectionValue(String imei, int value_motor_direction
            , GlCallback callback) {
        CTRL_MAP.clear();
        CTRL_MAP.put(ID_MOTOR_DIRECTION, value_motor_direction);
        CTRL_MAP.put(ID_MOTOR_ON, 1);
        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }

    public static void setLEDValue(String imei
            , int value_led_r
            , int value_led_g
            , int value_led_b
            , GlCallback callback) {
        CTRL_MAP.clear();
        CTRL_MAP.put(ID_LED_R, value_led_r);
        CTRL_MAP.put(ID_LED_G, value_led_g);
        CTRL_MAP.put(ID_LED_B, value_led_b);
        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    }


    //    public static void commitSet(String imei, GlCallback callback) {
    //        GlEngine.controlDevice(imei, CTRL_MAP, callback);
    //        CTRL_MAP.clear();
    //    }
    //
    //    public static void commitRequest(String imei, RequestDeviceValueCallback callback) {
    //        GlEngine.requestDeviceValue(imei, REQUEST_SET, callback);
    //        REQUEST_SET.clear();
    //    }

}
